package com.bmf.module.examination.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bmf.constant.AdminResultEnum;
import com.bmf.enums.QuestionDifficultyLevel;
import com.bmf.module.examination.entity.SelectionStrategy;
import com.bmf.module.examination.entity.SelectionStrategyQuestion;
import com.bmf.module.examination.mapper.SelectionStrategyMapper;
import com.bmf.module.examination.service.SelectionStrategyQuestionService;
import com.bmf.module.examination.service.SelectionStrategyService;
import com.bmf.module.examination.vo.SelectionStrategyCreateVo;
import com.bmf.module.examination.vo.SelectionStrategyResultVo;
import com.bmf.module.examination.vo.SelectionStrategyUpdateVo;
import com.bmf.utils.BeanCopyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * (SelectionStrategy)表服务实现类
 *
 * @author makejava
 * @since 2022-12-01 15:20:35
 */
@Service("selectionStrategyService")
public class SelectionStrategyServiceImpl extends ServiceImpl<SelectionStrategyMapper, SelectionStrategy> implements SelectionStrategyService {

    @Autowired
    private SelectionStrategyQuestionService selectionStrategyQuestionService;

    @Override
    public Integer insert(SelectionStrategyCreateVo selectionStrategyCreateVo) {
        SelectionStrategy selectionStrategy = BeanCopyUtils.copyBean(selectionStrategyCreateVo, SelectionStrategy.class);

        save(selectionStrategy);
        return selectionStrategy.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SelectionStrategyUpdateVo selectionStrategyUpdateVo) {
        SelectionStrategy byId = getById(selectionStrategyUpdateVo.getId());
        SelectionStrategy selectionStrategy = BeanCopyUtils.copyBean(selectionStrategyUpdateVo, SelectionStrategy.class);
        boolean b = updateById(selectionStrategy);
        AdminResultEnum.UPDATE_EXCEPTION.assertIsTrue(b);
        //修改题目分数
        if(selectionStrategyUpdateVo.getScore() != byId.getScore()){
            List<SelectionStrategyQuestion> bySelectionStrategyId = selectionStrategyQuestionService.getBySelectionStrategyId(byId.getId());
            if(CollUtil.isNotEmpty(bySelectionStrategyId)){
                selectionStrategyQuestionService.updateBatchById(bySelectionStrategyId.stream().peek(s -> s.setScore(selectionStrategyUpdateVo.getScore())).collect(Collectors.toList()));
            }
        }
    }

    @Override
    public Map<Integer, List<SelectionStrategyResultVo>> getSelectionStrategyList(List<Integer> bigQuestionIds) {
        LambdaQueryWrapper<SelectionStrategy> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SelectionStrategy::getBigQuestionId, bigQuestionIds);
        List<SelectionStrategy> list = list(wrapper);
        if(CollUtil.isEmpty(list)){
            return null;
        }
        Map<Integer, List<SelectionStrategyResultVo>> map = bigQuestionIds.stream().collect(Collectors.toMap(Function.identity(), s -> new ArrayList<>()));
        for (SelectionStrategy selectionStrategy : list) {
            List<SelectionStrategyResultVo> selectionStrategyResultVos = map.get(selectionStrategy.getBigQuestionId());
            if(selectionStrategyResultVos!=null){
                selectionStrategyResultVos.add(BeanCopyUtils.copyBean(selectionStrategy,SelectionStrategyResultVo.class));
            }
        }
        return map;
    }

    @Override
    public Map<String,List<SelectionStrategyResultVo>> select(List<Integer> ids) {
        if(CollUtil.isEmpty(ids)){
            return null;
        }
        LambdaQueryWrapper<SelectionStrategy> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SelectionStrategy::getBigQuestionId, ids);
        List<SelectionStrategy> list = list(wrapper);
        if(CollUtil.isEmpty(list)){
            return null;
        }
        //计算题目的各类型数量
        Map<Integer,Map<Integer, Long>> countMap = selectionStrategyQuestionService.getCountMapByExaminationId(list.get(0).getExaminationId());
        if(CollUtil.isNotEmpty(countMap)){
            Map<Integer, List<SelectionStrategyResultVo>> map = list.stream()
                    .map(s -> {
                        SelectionStrategyResultVo selectionStrategyResultVo = BeanCopyUtils.copyBean(s, SelectionStrategyResultVo.class);
                        Map<Integer, Long> integerLongMap = countMap.get(s.getId());
                        if(integerLongMap!=null){
                            Long difficultyNum = countMap.get(s.getId()).get(QuestionDifficultyLevel.DIFFICULTY.getCode());
                            if(difficultyNum==null){
                                difficultyNum = new Long(0);
                            }
                            selectionStrategyResultVo.setDifficultyNum(difficultyNum.intValue());
                            Long easilyNum = countMap.get(s.getId()).get(QuestionDifficultyLevel.EASILY.getCode());
                            if(easilyNum==null){
                                easilyNum = new Long(0);
                            }
                            selectionStrategyResultVo.setEasilyNum(easilyNum.intValue());
                            Long secondaryNum = countMap.get(s.getId()).get(QuestionDifficultyLevel.SECONDARY.getCode());
                            if(secondaryNum==null){
                                secondaryNum = new Long(0);
                            }
                            selectionStrategyResultVo.setSecondaryNum(secondaryNum.intValue());
                            Long unlimitedDifficultyNum = countMap.get(s.getId()).get(QuestionDifficultyLevel.UNLIMITEDDIFFICULTY.getCode());
                            if(unlimitedDifficultyNum==null){
                                unlimitedDifficultyNum = new Long(0);
                            }
                            selectionStrategyResultVo.setUnlimitedDifficultyNum(unlimitedDifficultyNum.intValue());
                            selectionStrategyResultVo.setTotalNum(difficultyNum.intValue()+easilyNum.intValue()+secondaryNum.intValue()+unlimitedDifficultyNum.intValue())
                                    .setSelectNum(s.getDifficulty()+s.getEasily()+s.getSecondary()+s.getUnlimitedDifficulty());
                        }else{
                            selectionStrategyResultVo.setSecondaryNum(0).setEasilyNum(0).setDifficultyNum(0).setUnlimitedDifficultyNum(0)
                                    .setSelectNum(s.getDifficulty()+s.getEasily()+s.getSecondary()+s.getUnlimitedDifficulty()).setTotalNum(0);
                        }
                        return selectionStrategyResultVo;
                    })
                    .collect(Collectors.groupingBy(SelectionStrategyResultVo::getBigQuestionId));
            return ids.stream().collect(Collectors.toMap(s -> s + "", s -> map.get(s)==null?new ArrayList<>():map.get(s)));
        }
        Map<Integer, List<SelectionStrategyResultVo>> collect = BeanCopyUtils.copyBeanList(list, SelectionStrategyResultVo.class).stream()
                .peek(s->{
                    s.setDifficultyNum(0).setEasilyNum(0).setSecondaryNum(0).setUnlimitedDifficultyNum(0).setTotalNum(0)
                            .setSelectNum(s.getDifficulty()+s.getEasily()+s.getSecondary()+s.getUnlimitedDifficulty());
                })
                .collect(Collectors.groupingBy(SelectionStrategyResultVo::getBigQuestionId));
        return ids.stream().collect(Collectors.toMap(s -> s + "", s -> collect.get(s)==null?new ArrayList<>():collect.get(s)));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> ids) {
        removeByIds(ids);
        //删除选择的题目
        selectionStrategyQuestionService.removeBySelectionStrategyIds(ids);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateScoreByBigQuestionId(Integer id, Double score) {
        LambdaQueryWrapper<SelectionStrategy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SelectionStrategy::getBigQuestionId, id);
        List<SelectionStrategy> list = list(queryWrapper);
        if(CollUtil.isEmpty(list)){
            return;
        }
        //1修改策略所有分数
        LambdaUpdateWrapper<SelectionStrategy> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(SelectionStrategy::getBigQuestionId, id).set(SelectionStrategy::getScore, score);
        update(wrapper);
        //2.修改关联题目所有分数
        List<Integer> ids = list.stream().map(SelectionStrategy::getId).collect(Collectors.toList());
        LambdaUpdateWrapper<SelectionStrategyQuestion> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(SelectionStrategyQuestion::getSelectionStrategyId, ids).set(SelectionStrategyQuestion::getScore, score);
        selectionStrategyQuestionService.update(updateWrapper);
    }

    @Override
    public List<SelectionStrategy> getByExaminationIds(List<Integer> ids) {
        LambdaQueryWrapper<SelectionStrategy> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SelectionStrategy::getExaminationId, ids);
        return list(wrapper);
    }

    @Override
    public void deleteByExaminationIds(List<Integer> ids) {
        //1.删除策略
        LambdaQueryWrapper<SelectionStrategy> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SelectionStrategy::getExaminationId, ids);
        remove(wrapper);
        //2.删除策略题目
        selectionStrategyQuestionService.deleteByExaminationIds(ids);
    }
}
